package com.ruoyi.energy.service.impl;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.energy.domain.EmsTimeSeriesData;
import com.ruoyi.energy.service.IEmsDeviceDataStatisticsService;
import com.ruoyi.energy.service.ITDengineTimeSeriesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 设备数据统计服务实现类
 * 基于TDengine实现设备数据统计、趋势分析等功能
 * 
 * @author ruoyi
 * @date 2025-06-30
 */
@Service
public class EmsDeviceDataStatisticsServiceImpl implements IEmsDeviceDataStatisticsService {
    
    private static final Logger log = LoggerFactory.getLogger(EmsDeviceDataStatisticsServiceImpl.class);
    
    @Autowired
    private ITDengineTimeSeriesService tdengineTimeSeriesService;
    
    @Override
    public Map<String, Object> getDeviceOverviewStatistics() {
        try {
            Map<String, Object> overview = new HashMap<>();
            
            // 获取设备在线状态统计
            Map<String, Long> onlineStats = tdengineTimeSeriesService.selectDeviceOnlineStatistics();
            overview.put("onlineDevices", onlineStats.getOrDefault("online", 0L));
            overview.put("offlineDevices", onlineStats.getOrDefault("offline", 0L));
            overview.put("totalDevices", onlineStats.values().stream().mapToLong(Long::longValue).sum());
            
            // 获取今日数据总量
            Date today = new Date();
            Calendar cal = Calendar.getInstance();
            cal.setTime(today);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            Date startOfDay = cal.getTime();
            
            long todayDataCount = tdengineTimeSeriesService.countDeviceData(null, startOfDay, today);
            overview.put("todayDataCount", todayDataCount);
            
            return overview;
        } catch (Exception e) {
            log.error("获取设备概览统计失败", e);
            return new HashMap<>();
        }
    }
    
    @Override
    public List<Map<String, Object>> getDeviceEnergyStatistics(String deviceCode, String energyType, 
                                                               Date startTime, Date endTime, String groupBy) {
        try {
            // 根据groupBy确定时间间隔
            String interval;
            switch (groupBy.toLowerCase()) {
                case "hour":
                    interval = "1h";
                    break;
                case "day":
                    interval = "1d";
                    break;
                case "month":
                    interval = "30d";
                    break;
                default:
                    interval = "1h";
            }
            
            List<Map<String, Object>> result;
            if (StringUtils.isNotEmpty(deviceCode)) {
                // 单设备能耗统计
                result = tdengineTimeSeriesService.selectAggregatedDataByDevice(deviceCode, startTime, endTime, interval);
            } else {
                // 多设备能耗统计 - 获取所有设备的最新数据作为替代
                List<EmsTimeSeriesData> latestData = tdengineTimeSeriesService.selectAllDevicesLatestData();
                result = new ArrayList<>();
                for (EmsTimeSeriesData data : latestData) {
                    Map<String, Object> item = new HashMap<>();
                    item.put("device_code", data.getDeviceCode());
                    item.put("avg_power", data.getPower());
                    item.put("total_energy", data.getTotalEnergy());
                    item.put("_wstart", new Date());
                    result.add(item);
                }
            }

            // 如果查询结果为空，尝试查询最近的数据
            if (result.isEmpty() && StringUtils.isNotEmpty(deviceCode)) {
                log.warn("能耗统计查询结果为空，尝试查询最近30天数据");
                Date newStartTime = new Date(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000);
                Date newEndTime = new Date();
                result = tdengineTimeSeriesService.selectAggregatedDataByDevice(deviceCode, newStartTime, newEndTime, interval);
            }

            return result;
        } catch (Exception e) {
            log.error("获取设备能耗统计失败", e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public Map<String, Object> getDeviceStatusStatistics(String deviceCode, Date startTime, Date endTime) {
        try {
            if (StringUtils.isNotEmpty(deviceCode)) {
                // 单设备状态统计
                return tdengineTimeSeriesService.selectDeviceDataQualityStatistics(deviceCode, startTime, endTime);
            } else {
                // 所有设备状态统计
                return new HashMap<>();
            }
        } catch (Exception e) {
            log.error("获取设备运行状态统计失败", e);
            return new HashMap<>();
        }
    }
    
    @Override
    public Map<String, Object> getDeviceEfficiencyAnalysis(String deviceCode, Date startTime, Date endTime) {
        try {
            return tdengineTimeSeriesService.selectDeviceEfficiencyAnalysis(deviceCode, startTime, endTime);
        } catch (Exception e) {
            log.error("获取设备效率分析失败: {}", deviceCode, e);
            return new HashMap<>();
        }
    }
    
    @Override
    public List<Map<String, Object>> getDeviceLoadTrend(String deviceCode, Date startTime, Date endTime, String interval) {
        try {
            return tdengineTimeSeriesService.selectDeviceLoadAnalysis(deviceCode, startTime, endTime, interval);
        } catch (Exception e) {
            log.error("获取设备负载趋势失败: {}", deviceCode, e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public Map<String, Object> getDeviceAlarmStatistics(String deviceCode, Date startTime, Date endTime) {
        try {
            List<Map<String, Object>> alarmData = tdengineTimeSeriesService.selectDeviceAlarmData(deviceCode, startTime, endTime);
            
            Map<String, Object> statistics = new HashMap<>();
            statistics.put("totalAlarms", alarmData.size());
            
            // 按告警类型分类统计
            Map<String, Integer> alarmTypes = new HashMap<>();
            for (Map<String, Object> alarm : alarmData) {
                String quality = (String) alarm.get("quality");
                String status = (String) alarm.get("status");
                
                if (!"GOOD".equals(quality)) {
                    alarmTypes.put("quality", alarmTypes.getOrDefault("quality", 0) + 1);
                }
                if (!"ONLINE".equals(status)) {
                    alarmTypes.put("offline", alarmTypes.getOrDefault("offline", 0) + 1);
                }
                
                // 检查其他告警条件
                Object power = alarm.get("power");
                Object temperature = alarm.get("temperature");
                if (power != null && ((Number) power).doubleValue() > 1000) {
                    alarmTypes.put("overload", alarmTypes.getOrDefault("overload", 0) + 1);
                }
                if (temperature != null && ((Number) temperature).doubleValue() > 80) {
                    alarmTypes.put("overheat", alarmTypes.getOrDefault("overheat", 0) + 1);
                }
            }
            
            statistics.put("alarmTypes", alarmTypes);
            return statistics;
        } catch (Exception e) {
            log.error("获取设备告警统计失败: {}", deviceCode, e);
            return new HashMap<>();
        }
    }
    
    @Override
    public List<Map<String, Object>> getDeviceComparisonAnalysis(List<String> deviceCodes, Date startTime, 
                                                                Date endTime, List<String> metrics) {
        try {
            return tdengineTimeSeriesService.selectMultiDeviceComparisonData(deviceCodes, startTime, endTime, "1h");
        } catch (Exception e) {
            log.error("获取设备对比分析失败", e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public Map<String, Object> getDevicePeakValleyAnalysis(String deviceCode, Date startTime, Date endTime) {
        try {
            return tdengineTimeSeriesService.selectDevicePeakValleyAnalysis(deviceCode, startTime, endTime);
        } catch (Exception e) {
            log.error("获取设备峰谷电分析失败: {}", deviceCode, e);
            return new HashMap<>();
        }
    }
    
    @Override
    public Map<String, Object> getDeviceDataQualityReport(String deviceCode, Date startTime, Date endTime) {
        try {
            if (StringUtils.isNotEmpty(deviceCode)) {
                return tdengineTimeSeriesService.selectDeviceDataQualityStatistics(deviceCode, startTime, endTime);
            } else {
                // 所有设备数据质量报告 - 需要实现
                return new HashMap<>();
            }
        } catch (Exception e) {
            log.error("获取设备数据质量报告失败", e);
            return new HashMap<>();
        }
    }
    
    @Override
    public List<Map<String, Object>> getDeviceEnergyRanking(String energyType, Date startTime, Date endTime, int limit) {
        try {
            return tdengineTimeSeriesService.selectDeviceEnergyRanking(energyType, startTime, endTime, limit);
        } catch (Exception e) {
            log.error("获取设备能耗排行榜失败", e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public List<Map<String, Object>> getDeviceRealtimeMonitorData(List<String> deviceCodes) {
        try {
            if (deviceCodes != null && !deviceCodes.isEmpty()) {
                Map<String, com.ruoyi.energy.domain.EmsTimeSeriesData> latestData =
                    tdengineTimeSeriesService.selectLatestDataByDevices(deviceCodes);

                List<Map<String, Object>> result = new ArrayList<>();
                for (Map.Entry<String, com.ruoyi.energy.domain.EmsTimeSeriesData> entry : latestData.entrySet()) {
                    Map<String, Object> deviceData = new HashMap<>();
                    deviceData.put("deviceCode", entry.getKey());

                    // 格式化数据为前端期望的格式
                    Map<String, Object> data = new HashMap<>();
                    com.ruoyi.energy.domain.EmsTimeSeriesData timeSeriesData = entry.getValue();
                    data.put("power", timeSeriesData.getPower() != null ? timeSeriesData.getPower().doubleValue() : 0.0);
                    data.put("voltage", timeSeriesData.getVoltage() != null ? timeSeriesData.getVoltage().doubleValue() : 0.0);
                    data.put("current", timeSeriesData.getCurrent() != null ? timeSeriesData.getCurrent().doubleValue() : 0.0);
                    data.put("temperature", timeSeriesData.getTemperature() != null ? timeSeriesData.getTemperature().doubleValue() : 0.0);
                    data.put("totalEnergy", timeSeriesData.getTotalEnergy() != null ? timeSeriesData.getTotalEnergy().doubleValue() : 0.0);
                    data.put("status", timeSeriesData.getStatus());
                    data.put("quality", timeSeriesData.getQuality());

                    deviceData.put("data", data);
                    result.add(deviceData);
                }
                return result;
            } else {
                // 获取所有设备最新数据
                List<com.ruoyi.energy.domain.EmsTimeSeriesData> allLatestData =
                    tdengineTimeSeriesService.selectAllDevicesLatestData();

                List<Map<String, Object>> result = new ArrayList<>();
                for (com.ruoyi.energy.domain.EmsTimeSeriesData timeSeriesData : allLatestData) {
                    Map<String, Object> deviceData = new HashMap<>();
                    deviceData.put("deviceCode", timeSeriesData.getDeviceCode());

                    // 格式化数据为前端期望的格式
                    Map<String, Object> data = new HashMap<>();
                    data.put("power", timeSeriesData.getPower() != null ? timeSeriesData.getPower().doubleValue() : 0.0);
                    data.put("voltage", timeSeriesData.getVoltage() != null ? timeSeriesData.getVoltage().doubleValue() : 0.0);
                    data.put("current", timeSeriesData.getCurrent() != null ? timeSeriesData.getCurrent().doubleValue() : 0.0);
                    data.put("temperature", timeSeriesData.getTemperature() != null ? timeSeriesData.getTemperature().doubleValue() : 0.0);
                    data.put("totalEnergy", timeSeriesData.getTotalEnergy() != null ? timeSeriesData.getTotalEnergy().doubleValue() : 0.0);
                    data.put("status", timeSeriesData.getStatus());
                    data.put("quality", timeSeriesData.getQuality());

                    deviceData.put("data", data);
                    result.add(deviceData);
                }
                return result;
            }
        } catch (Exception e) {
            log.error("获取设备实时监控数据失败", e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public List<Map<String, Object>> exportDeviceStatisticsReport(String reportType, String deviceCode, 
                                                                  Date startTime, Date endTime) {
        try {
            List<String> fields = Arrays.asList("ts", "device_code", "power", "total_energy", 
                                               "voltage", "current", "temperature", "status", "quality");
            
            if (StringUtils.isNotEmpty(deviceCode)) {
                return tdengineTimeSeriesService.selectDeviceDataForExport(deviceCode, startTime, endTime, fields);
            } else {
                // 导出所有设备数据 - 需要实现
                return new ArrayList<>();
            }
        } catch (Exception e) {
            log.error("导出设备统计报表失败", e);
            return new ArrayList<>();
        }
    }
}
